//  Implementazione di una coda di max-priorità tramite heap.
//  La priorità è associata al campo chiave.
//  La massima priorità corrsiponde al valore più alto della chiave.
//  PriorityQueue.c
//  TecnicheDiProgrammazione
//
//

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include "PriorityQueue.h"
#include "Heap.h"

//Definizione della struttura dell'heap
struct SPQueue{
    THeap *heap;
};

/*
 Consente di creare una nuova coda di priorità allocando tutte le
 risorse necessarie
 @return la nuova coda di priorità creata
 */
TPQueue *priorityqueue_create(){
    TPQueue *q = (TPQueue*)malloc(sizeof(TPQueue));
    assert(q!=NULL);
    q->heap = heap_create();
    return q;
}

/*
 Dealloca le risorse associate alla coda passata come parametro.
 @param q riferimento alla coda da deallocare
 */
void priorityqueue_destroy(TPQueue *q){
    heap_destroy(q->heap);
    free(q);
    q = NULL;
}

/*
 Restituisce il riferimento all'elemento a massima priorità presente nella coda
 @param q La coda da cui prelevare l'elemento
 @return Riferimento al primo elemento della coda
 */
TInfo* priorityqueue_get_maximum(TPQueue *q){
    return heap_get_at_index(q->heap, 0);
}

/*
 Rimuove l'elemento a massima priorità dalla coda
 @param q La coda da cui rimuovere l'elemento
 @return L'elemento rimosso dalla coda
 */
TInfo priorityqueue_remove_maximum(TPQueue *q){
    TInfo returnValue = *heap_get_at_index(q->heap, 0);
    heap_delete_at_index(q->heap, 0);
    return returnValue;
}

/*
 Consente di cambiare la priorità ad un elemento della coda
 @param q Riferimento alla coda su cui operare
 @param elem Indice dell'elemento a cui si desidera cambiare la priorità
 @param newPriority Nuova priorità dell'elemento
 */
void priorityqueue_change_priority(TPQueue *q, int elem, int newPriority){
    heap_set_key(q->heap, elem, newPriority);
}

/*
 Consente di inserire un nuovo elemento all'interno della coda.
 @param q Coda in cui inserire l'elemento
 @param info Elemento da inserire
 */
void priorityqueue_insert(TPQueue *q, TInfo info){
    heap_insert(q->heap, info);
}



